package com.listeningframework.boot.autoconfigure.webmvc;

import com.listeningframework.boot.autoconfigure.webmvc.validate.ValidationResult;
import com.listeningframework.boot.autoconfigure.webmvc.validate.Validations;
import com.listeningframework.boot.commons.http.HttpWebUtils;
import com.listeningframework.boot.commons.reflect.BeanUtils;
import com.listeningframework.boot.domains.Domains;
import com.listeningframework.boot.domains.Pagination;
import com.listeningframework.boot.domains.Paging;
import com.listeningframework.boot.domains.ResponseBodys;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * Web端基类
 *
 * @author Listening
 * @version $Id: ListeningWebController.java, v 0.1 2014年6月6日 下午11:07:00 Listening Exp $
 */
public class BaseController {
    /**
     * 日志工具
     */
    protected Logger LOG = LoggerFactory.getLogger(BaseController.class);
    /**
     * 成功
     */
    protected static final String SUCCESS = "0";
    /**
     * 失败
     */
    protected static final String FAILURE = "1";

    protected <T> ValidationResult validate(T t) {
        return Validations.validate(t);
    }

    protected <T> String validateHasError(T t) {
        ValidationResult result = Validations.validate(t);
        return result.hasErrors() ? result.getErrorMsg() : null;
    }

    /**
     * 查询分页信息
     *
     * @param request      HttpServletRequest
     * @param pageNoName   页码名称
     * @param pageSizeName 页面大小名称
     * @return Paging
     */
    protected Paging getPaging(HttpServletRequest request, String pageNoName, String pageSizeName) {
        Integer pageNo = HttpWebUtils.getIntValue(request, pageNoName, 1);
        Integer pageSize = HttpWebUtils.getIntValue(request, pageSizeName, 20);
        pageNo = (pageNo <= 0) ? 1 : pageNo;
        pageSize = (pageSize <= 0) ? 20 : pageSize;
        return new Paging(pageNo, pageSize);
    }

    /**
     * 转换分页对象为返回对象
     *
     * @param pagination 分页信息
     * @param <T> 返回类型泛型
     * @return ResponseBodys
     */
    protected <T> ResponseBodys<T> convertResponseBody(Pagination<T> pagination) {
        ResponseBodys<T> respBody = Domains.newResponseBody();
        respBody.setResponseSuccess();
        if (pagination == null) {
            return respBody;
        }
        respBody.setResults(pagination.getTotalCount());
        respBody.addAllData(pagination.getDataList());
        return respBody;
    }

    /**
     * Convert CallBack Interface
     *
     * @author lixining
     * @version $Id: BaseController.java, v 0.1 2016年2月15日 下午3:35:04 lixining Exp $
     */
    protected interface Convertable<SRC, DEST> {
        public DEST convert(SRC src);
    }

    /**
     * 转换分页对象为ResponseBodys对象
     *
     * @param pagination 分页对象
     * @param callback 个性设置回调
     * @param <SRC> 源类型
     * @param <DEST> 目标类型
     * @return ResponseBodys
     */
    protected <SRC, DEST> ResponseBodys<DEST> convertResponseBody(Pagination<SRC> pagination,
                                                                  Convertable<SRC, DEST> callback) {
        ResponseBodys<DEST> respBody = Domains.newResponseBody();
        respBody.setResponseSuccess();
        if (pagination == null) {
            return respBody;
        }
        respBody.setResults(pagination.getTotalCount());
        List<SRC> srcList = pagination.getDataList();
        if (CollectionUtils.isEmpty(srcList)) {
            return respBody;
        }
        List<DEST> dataList = new ArrayList<DEST>();
        for (SRC src : srcList) {
            dataList.add(callback.convert(src));
        }
        respBody.addAllData(dataList);
        return respBody;
    }

    /**
     * Convert RespBody
     *
     * @param pagination 分页对象
     * @param dest 目标类型
     * @param <T> 返回泛型
     * @return ResponseBodys
     */
    protected <T> ResponseBodys<T> convertResponseBody(Pagination<?> pagination, Class<T> dest) {
        ResponseBodys<T> respBody = Domains.newResponseBody();
        respBody.setResponseSuccess();
        if (pagination == null) {
            return respBody;
        }
        respBody.setResults(pagination.getTotalCount());
        List<?> dataList = pagination.getDataList();
        if (CollectionUtils.isEmpty(dataList)) {
            return respBody;
        }
        for (Object obj : dataList) {
            respBody.addData(BeanUtils.copy(obj, dest));
        }
        return respBody;
    }
}
